package rand

import (
	"duanju-mq/pkg/rand"
	"reflect"
)

func In(min int, max int) int { return rand.In(min, max) }

func Lt(n int) int { return rand.Lt(n) }

func Le(n int) int { return rand.Le(n) }

//

type Weighter interface {
	Weight() int
}

type WeightSelector func() (obj any, index int, total int, rnd int)

func MakeWeightSelector(ws ...Weighter) WeightSelector {
	total := 0
	for _, w := range ws {
		if ww := w.Weight(); ww > 0 {
			total += ww
		}
	}
	return func() (any, int, int, int) {
		if total > 0 {
			rnd := In(1, total)
			acc := 0
			for i, w := range ws {
				if ww := w.Weight(); ww > 0 {
					acc += ww
					if rnd <= acc {
						return w, i, total, rnd
					}
				}
			}
		}
		return nil, -1, 0, 0
	}
}

func WeightSelect(ws ...Weighter) (obj any, index int, total int, rnd int) {
	return MakeWeightSelector(ws...)()
}

//

func Shuffle(slice any) {
	v := reflect.ValueOf(slice)
	if v.Kind() != reflect.Slice {
		panic("rand.Shuffle: expect slice")
	}
	n := v.Len()
	if n < 2 {
		return
	}
	swap := reflect.Swapper(slice)
	for i := n - 1; i > 0; i-- {
		j := Le(i)
		swap(i, j)
	}
}

//

var (
	UpperChars   = rand.UpperChars
	LowerChars   = rand.LowerChars
	NumChars     = rand.NumChars
	SpecialChars = rand.SpecialChars
	ULNChars     = rand.ULNChars
)

func RandStr(length int, charset ...[]rune) string { return rand.RandStr(length, charset...) }
